/*
 * Copyright 2012 Marsrutai.lt
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package lt.marsrutai.mobile.android.manager;

import java.util.ArrayList;
import java.util.List;

import lt.marsrutai.mobile.android.R;
import lt.marsrutai.mobile.android.activity.intent.DataDownloadServiceIntentHolder;
import lt.marsrutai.mobile.android.cache.DataCacheUpdater;
import lt.marsrutai.mobile.android.cache.UpdateCacheRequest;
import lt.marsrutai.mobile.android.dao.exception.BackendException;
import lt.marsrutai.mobile.android.util.ActivityUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.widget.CheckBox;

/**
 *
 * @author Martynas
 *
 */
public class CacheUpdateManager {

    private DataCacheUpdater dataCacheUpdater;

    public CacheUpdateManager(DataCacheUpdater dataCacheUpdater) {
        this.dataCacheUpdater = dataCacheUpdater;
    }

    public void checkForCacheUpdates(final Activity activity, final boolean verbose) {
        // show progress dialog, while checking whether cache update is needed
        final ProgressDialog progressDialog = new ProgressDialog(activity);
        progressDialog.setMessage(activity.getString(R.string.update_request_cache_checking));
        progressDialog.setCancelable(false);
        progressDialog.setIndeterminate(true);

        if (verbose) {
            progressDialog.show();
        }

        new Thread(new Runnable() {

            @Override
            public void run() {
                // perform check in a separate non-ui thread
                try {
                    final boolean updateNeeded = dataCacheUpdater.isUpdateNeeded();

                    if (!activity.isFinishing()) {
                        // after check is complete, go back to ui thread,
                        // to dismiss progress bar and show result dialogs
                        activity.runOnUiThread(new Runnable() {
    
                            @Override
                            public void run() {
                                if (verbose) {
                                    progressDialog.dismiss();
                                }
    
                                if (updateNeeded) {
                                    showUpdateNeededDialog(activity);
                                }
                                else {
                                    if (verbose) {
                                        showNoUpdateNeededDialog(activity);
                                    }
                                }
                            }
                        });
                    }
                }
                catch (BackendException ex) {
                    if (!activity.isFinishing()) {
                        activity.runOnUiThread(new Runnable() {
    
                            @Override
                            public void run() {
                                if (verbose) {
                                    progressDialog.dismiss();
                                    showNoDataDialog(activity);
                                }
                            }
                        });
                    }
                }
            }
        }).start();
    }

    private void performUpdate(final Activity activity) {
        performUpdate(activity, null);
    }

    public void performUpdate(final Activity activity, final UpdateCacheRequest updateRequest) {

        new Thread(new Runnable() {

            @Override
            public void run() {

                // perform check in a separate non-ui thread
                List<UpdateCacheRequest> updatableScopes = null;
                if (null != updateRequest) {
                    updatableScopes = new ArrayList<UpdateCacheRequest>();
                    updatableScopes.add(updateRequest);
                }
                else {
                    updatableScopes = dataCacheUpdater.getUpdatableScopes();
                }

                for (UpdateCacheRequest request : updatableScopes) {
                    DataDownloadServiceIntentHolder intentHolder = new DataDownloadServiceIntentHolder(activity);
                    intentHolder.setUpdateCacheRequest(request);
                    activity.startService(intentHolder.getIntent());
                }

            }
        }).start();
    }

    public void cancelUpdate(final Activity activity, final UpdateCacheRequest updateRequest) {
        DataDownloadServiceIntentHolder intentHolder = new DataDownloadServiceIntentHolder(activity);
        intentHolder.setUpdateCacheRequest(updateRequest);
        intentHolder.setActionStart(false);
        activity.startService(intentHolder.getIntent());
    }

    private void showUpdateNeededDialog(final Activity activity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setIcon(android.R.drawable.ic_dialog_alert).setTitle(activity.getString(R.string.need_confirmation))
                .setMessage(activity.getString(R.string.update_request_cache_confirm)).setCancelable(false)
                .setPositiveButton(activity.getString(R.string.yes), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        performUpdate(activity);
                    }

                }).setNegativeButton(activity.getString(R.string.no), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }

                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    private void showNoUpdateNeededDialog(final Activity activity) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setMessage(activity.getString(R.string.update_request_cache_not_needed)).setCancelable(false)
                .setPositiveButton(activity.getString(R.string.update_regardless), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        performUpdate(activity);
                    }

                }).setNegativeButton(activity.getString(R.string.ok), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }

                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    public void showDownloadScopeAdviceDialog(final Activity activity, final UpdateCacheRequest updateRequest) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setIcon(android.R.drawable.ic_dialog_alert).setTitle(activity.getString(R.string.need_confirmation))
                .setMessage(activity.getString(R.string.download_scope_data_advice)).setCancelable(false)
                .setPositiveButton(activity.getString(R.string.yes), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        performUpdate(activity, updateRequest);
                    }

                }).setNegativeButton(activity.getString(R.string.no), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }

                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    public void showScopeDeleteConfirmationDialog(final Activity activity, final String scopeFolder, final CheckBox checkbox) {
        showDeleteConfirmationDialog(activity, scopeFolder, checkbox);
    }

    public void showAllDataDeleteConfirmationDialog(final Activity activity) {
        showDeleteConfirmationDialog(activity, null, null);
    }

    public void showDeleteConfirmationDialog(final Activity activity, final String scopeFolder, final CheckBox checkbox) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setIcon(android.R.drawable.ic_dialog_alert)
                .setTitle(activity.getString(R.string.need_confirmation))
                .setMessage(
                        activity.getString(null != scopeFolder ? R.string.clean_scope_data_confirmation
                                : R.string.clean_all_data_confirmation)).setCancelable(false)
                .setPositiveButton(activity.getString(R.string.yes), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        performDelete(activity, scopeFolder);
                    }

                }).setNegativeButton(activity.getString(R.string.no), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();

                        if (null != checkbox) {
                            checkbox.setChecked(true);
                        }
                    }

                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    public void performDelete(final Activity activity, final String scopeFolder) {
        final ProgressDialog progressDialog = new ProgressDialog(activity);
        progressDialog.setMessage(activity.getString(R.string.clean_scope_data_in_progress));
        progressDialog.setCancelable(false);
        progressDialog.setIndeterminate(true);
        progressDialog.show();

        new Thread(new Runnable() {

            @Override
            public void run() {
                // perform clean in a separate non-ui thread
                if (null != scopeFolder) {
                    dataCacheUpdater.clean(scopeFolder);
                }
                else {
                    dataCacheUpdater.clean();
                }

                if (!activity.isFinishing()) {
                    // after clean is complete, go back to ui thread,
                    // to dismiss progress bar and show result dialogs                
                    activity.runOnUiThread(new Runnable() {
    
                        @Override
                        public void run() {
                            progressDialog.dismiss();
                            showOkDialog(activity, activity.getString(R.string.clean_scope_data_ok));
                        }
                    });
                }
            }
        }).start();
    }

    private void showNoDataDialog(Activity activity) {
        showOkDialog(activity, activity.getString(R.string.update_request_cache_no_data));
    }

    private void showOkDialog(final Activity activity, String message) {
        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setMessage(message).setCancelable(false)
                .setNegativeButton(activity.getString(R.string.ok), new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.dismiss();

                        ActivityUtils.restartFirstActivity(activity);
                    }

                });
        AlertDialog alert = builder.create();
        alert.show();
    }
}
